[HVM][VMX] Fix for CR8 acceleration on 64bit guest.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 1 Dec 2006 09:48:18 +0000 (09:48 +0000)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Fri, 1 Dec 2006 09:48:18 +0000 (09:48 +0000)
For current CR8 acceleration, we do not call update_tpr_threshold() at
every VMEXIT. But at some situations, we cannot inject guest
interrupts in time. And at some critical time, it will bring up a blue
screen to 64bit Windows guest.

Now, we select to call update_tpr_threshold() at very VMEXIT
time. It's safe, and we do not see clear performance downgrade so
far.

Signed-off-by: Xiaohui Xin xiaohui.xin@intel.com
xen/arch/x86/hvm/vlapic.c
xen/arch/x86/hvm/vmx/io.c
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/vlapic.h

index 1c6bef005ebd6ed01b9ac8a0dcac4790b77c6e21..60e6171c477eb3a438263827fe048cf2ab7e8557 100644 (file)
@@ -119,19 +119,16 @@ static int vlapic_find_highest_vector(u32 *bitmap)
 
 static int vlapic_test_and_set_irr(int vector, struct vlapic *vlapic)
 {
-    vlapic->flush_tpr_threshold = 1;
     return vlapic_test_and_set_vector(vector, vlapic->regs + APIC_IRR);
 }
 
 static void vlapic_set_irr(int vector, struct vlapic *vlapic)
 {
-    vlapic->flush_tpr_threshold = 1;
     vlapic_set_vector(vector, vlapic->regs + APIC_IRR);
 }
 
 static void vlapic_clear_irr(int vector, struct vlapic *vlapic)
 {
-    vlapic->flush_tpr_threshold = 1;
     vlapic_clear_vector(vector, vlapic->regs + APIC_IRR);
 }
 
@@ -634,7 +631,6 @@ static void vlapic_write(struct vcpu *v, unsigned long address,
     {
     case APIC_TASKPRI:
         vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
-        vlapic->flush_tpr_threshold = 1;
         break;
 
     case APIC_EOI:
@@ -667,10 +663,7 @@ static void vlapic_write(struct vcpu *v, unsigned long address,
             }
         }
         else
-        {
             vlapic->disabled &= ~VLAPIC_SW_DISABLED;
-            vlapic->flush_tpr_threshold = 1;
-        }
         break;
 
     case APIC_ESR:
@@ -925,8 +918,6 @@ static int vlapic_reset(struct vlapic *vlapic)
     vlapic_set_reg(vlapic, APIC_SPIV, 0xff);
     vlapic->disabled |= VLAPIC_SW_DISABLED;
 
-    vlapic->flush_tpr_threshold = 1;
-
     return 1;
 }
 
index 2f3cf623b1bf16f12a77e89f6d9b0817a41e9a2d..662a6697a067baabb0411a431256357c524ce5bd 100644 (file)
@@ -71,10 +71,6 @@ static void update_tpr_threshold(struct vlapic *vlapic)
 {
     int max_irr, tpr;
 
-    /* Clear the work-to-do flag /then/ do the work. */
-    vlapic->flush_tpr_threshold = 0;
-    mb();
-
     if ( !vlapic_enabled(vlapic) || 
          ((max_irr = vlapic_find_highest_irr(vlapic)) == -1) )
     {
@@ -95,7 +91,6 @@ asmlinkage void vmx_intr_assist(void)
     int highest_vector;
     unsigned long eflags;
     struct vcpu *v = current;
-    struct vlapic *vlapic = vcpu_vlapic(v);
     struct hvm_domain *plat=&v->domain->arch.hvm_domain;
     struct periodic_time *pt = &plat->pl_time.periodic_tm;
     unsigned int idtv_info_field;
@@ -110,8 +105,7 @@ asmlinkage void vmx_intr_assist(void)
 
     hvm_set_callback_irq_level();
 
-    if ( vlapic->flush_tpr_threshold )
-        update_tpr_threshold(vlapic);
+    update_tpr_threshold(vcpu_vlapic(v));
 
     has_ext_irq = cpu_has_pending_irq(v);
 
index 7d226e6ba124fd72a59e0725b016ac61dcffb1c6..58cca4bea46723f81966cb108eea1cdd22f70405 100644 (file)
@@ -2500,7 +2500,6 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
         break;
 
     case EXIT_REASON_TPR_BELOW_THRESHOLD:
-        vcpu_vlapic(v)->flush_tpr_threshold = 1;
         break;
 
     default:
index 003d93b3892c4d1c731c30d588c5e70ffa74b157..2053fc56eceaa30ad3f69f93cfdea72b9a498171 100644 (file)
@@ -54,7 +54,6 @@ struct vlapic {
     uint32_t           timer_divisor;
     struct timer       vlapic_timer;
     int                timer_pending_count;
-    int                flush_tpr_threshold;
     s_time_t           timer_last_update;
     struct page_info   *regs_page;
     void               *regs;